namespace Trader.Trading
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using BO.Interface;
    using Interface;

    public class PortfolioMember : IPortfolioMember
    {
        private readonly Dictionary<DateTime, int> datesUnits;
        private readonly IRecommendation recommendation;
        private DateTime? sellDate;

        public PortfolioMember(IRecommendation recommendation, DateTime buyDate, int units)
        {
            this.recommendation = recommendation;
            datesUnits = new Dictionary<DateTime, int>();
            SetNewUnitsCount(buyDate, units);
        }

        #region IPortfolioMember Members

        public DateTime? SellDate
        {
            get { return sellDate; }
        }

        public int Units(DateTime date)
        {
            if (date < datesUnits.Keys.Min())
            {
                return 0;
            }

            DateTime valueDate = datesUnits.Keys.Where(existingDate => existingDate <= date).Max();
            return datesUnits[valueDate];
        }

        public void SetSellDate(DateTime date)
        {
            sellDate = date;
        }

        public bool UpdateUnits(DateTime updateDate)
        {
            int dateUnits = Units(updateDate);
            int newUnits = recommendation.Stock.UpdateUnits(dateUnits, updateDate);
            if (newUnits != dateUnits)
            {
                SetNewUnitsCount(updateDate, newUnits);
                return true;
            }
            return false;
        }

        public IRecommendation Recommendation
        {
            get { return recommendation; }
        }

        public IStock Stock
        {
            get { return recommendation.Stock; }
        }

        public DateTime BuyDate
        {
            get { return datesUnits.Keys.Min(); }
        }

        public IMoney CalculateValue(DateTime valueDate)
        {
            return Stock.AsMoney(Units(valueDate), valueDate);
        }

        public void AdjustUnits(int newUnits, DateTime adjustDate)
        {
            SetNewUnitsCount(adjustDate, newUnits);
        }

        #endregion

        private void SetNewUnitsCount(DateTime buyDate, int units)
        {
            datesUnits.Add(buyDate, units);
        }

/*
        public override string ToString()
        {
            return recommendation.Stock + " " + units + " " + recommendation.Stock.AsMoney(units, buyDate);
        }
*/
    }
}